﻿using AutoMapper;
using HelenServer.UserCenter.Contracts;
using Microsoft.EntityFrameworkCore;

namespace HelenServer.UserCenter.Dal;

public class UserCenterProfile : Profile
{
    protected internal static UserCenterDbContext Context =>
        new Lazy<UserCenterDbContext>(() =>
    {
        var config = Helen.Services.GetRequiredService<IConfiguration>();
        var connectionString = config.GetConnectionString("master");

        return new UserCenterDbContext(new DbContextOptionsBuilder<UserCenterDbContext>().UseSqlServer(connectionString).Options);
    }).Value;

    public UserCenterProfile()
    {
        this.CreateMap<UserCreateModel, User>()
            .ForMember(dest => dest.Status, member => member.MapFrom(source => UserStatus.In))
            .ForMember(dest => dest.Department, member => member.MapFrom(source => MapVirtualDepartment(source.Department)))
            .ForMember(dest => dest.Position, member => member.MapFrom(source => MapPosition(source.Position)))
            .ForMember(dest => dest.Roles, member => member.MapFrom(source => MapRoles(source.Roles)));

        this.CreateMap<User, UserInfoModel>()
            .ForMember(dest => dest.Sex, member => member.MapFrom(source => source.Sex == 1 ? "男" : "女"))
            .ForMember(dest => dest.Status, member => member.MapFrom(source => source.Status == UserStatus.In ? "在岗" : "离职"));

        this.CreateMap<DepartmentCreateModel, Department>()
            .ForMember(dest => dest.Parent, member => member.MapFrom(source => MapVirtualDepartment(source.Parent)))
            .ForMember(dest => dest.Manager, member => member.MapFrom(source => MapDbUser(source.Manager)));

        this.CreateMap<Position, PositionCreateModel>().ReverseMap();
        this.CreateMap<Role, RoleInfoModel>().ReverseMap();

        AppDomain.CurrentDomain.ProcessExit += this.CurrentDomain_ProcessExit;
    }

    private void CurrentDomain_ProcessExit(object? sender, EventArgs e)
    {
        Context?.Dispose();
    }

    private static Department? MapVirtualDepartment(int? id)
    {
        return id is null or 0 ? null : new Department { Id = id.Value };
    }

    private static User? MapDbUser(int? id)
    {
        if (id is null or 0)
        {
            return null;
        }

        var entity = Context.Users.FirstOrDefault(n => n.Id == id.Value);

        return entity is not null ? entity : null;
    }

    private static Position? MapPosition(int? id)
    {
        if (id is null)
        {
            return null;
        }

        var result = Context.Positions.FirstOrDefault(n => n.Id == id);

        return result is not null ? result : null;
    }

    private static ICollection<Role> MapRoles(int[] roles)
    {
        var result = roles.Select(n => Context.Roles.First(e => e.Id == n));

        return result.ToList();
    }
}